﻿using Lf_Shop.Models;
using Lf_Shop.service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Transactions;

namespace Lf_Shop.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class OrderController : ControllerBase
    {
        private readonly ICarService _carService;
        private readonly IOrderService _orderService;
        /// <summary>
        /// 订单构造函数
        /// </summary>
        /// <param name="carService"></param>
        public OrderController(ICarService carService, IOrderService orderService)
        {
            _carService = carService;
            _orderService = orderService;
        }

        //把购物车商品生成订单和订单明细，进行结算，扣除商品库存，订单进入待发货状态【支付功能略过】
        /// <summary>
        /// 结算接口
        /// </summary>
        [Authorize]
        [HttpPost]
        public string Settlement()
        {
            //using(定义的对象)
            //{
            //    空间执行下 使用这个一个对象
            //}
            //如果执行到外面的空间 对象就会自动销毁
            //                开启事务
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    //1、把购物车商品取出来
                    var userId = Response.HttpContext.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value;

                    //获取到的用户购物车
                    var list = _carService.GetCarGoodsForSQL(Convert.ToInt32(userId));

                    //2、判断库存是否充足 哪个商品不足
                    if (!_orderService.CheckGoodStock(list, out string err))
                        return $"[{err}]库存不足";

                    //3、创建订单和订单明细
                    _orderService.CreateOrder(list, Convert.ToInt32(userId));

                    //4、扣除库存
                    _orderService.DiffGoodStock(list);

                    //5、清空购物车
                    _carService.RemoveCarForSQL(Convert.ToInt32(userId));

                    // 如果所有的操作都执行成功，则Complete()会被调用来提交事务
                    // 如果发生异常，则不会调用它并回滚事务
                    //提交事务
                    scope.Complete();
                    return "下单成功";
                }
                catch (Exception ex)
                {
                    // 处理异常
                    return "下单失败";
                }
            }
            //6、完成返回消息
        }

        //用户按照订单的状态查询自己的订单列表，查看订单商品，订单价格，订单状态等
        /// <summary>
        /// 用户订单列表
        /// </summary>
        [Authorize]
        [HttpPost]
        public GetUserOrderListResponse GetUserOrderList(GetUserOrderListRequest request)
        {
            var userId = Response.HttpContext.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value;
            //查询用户的订单
            var list = _orderService.GetUserOrderList(Convert.ToInt32(userId), request.OrderState, request.PageIndex, request.PageSize, out int total);
            var response = new GetUserOrderListResponse();
            response.Total = total;
            response.OrderList = list;
            return response;
        }

        //后台订单列表（查询所有用户下的订单，查询订单号，订单价格，下单用户，订单商品）
        /// <summary>
        /// 获取后台订单列表
        /// </summary>
        [HttpPost]
        public GetAdminOrderListResponse GetAdminOrderList(GetUserOrderListRequest request)
        {
            //查询用户的订单
            var list = _orderService.GetAdminOrderList(request.OrderState, request.PageIndex, request.PageSize, out int total);
            var response = new GetAdminOrderListResponse();
            response.Total = total;
            response.OrderList = list;
            return response;
        }

        //后台发货功能（点击发货按钮输入快递公司和快递单号，对订单状态进行更新，更新为已发货状态）
        //接口需求 本质
        //输入 订单ID
        //对订单数据的更新 快递公司 快递单号 订单状态
        [HttpPost]
        public string SendOrder(SendOrderRequest request)
        {
            //订单发货
            _orderService.SendOrder(request.OrderId, request.ShipCom, request.ShipNum);
            return "发货成功";
        }
    }
}
